package net.wesc.ac.server;

/**
 * Huckel半经验方程是E. Huckel于1925年在Debye-Huckel模型的基础上加以修正提出的。改进之处在于添加了活度系数随
 * 溶液离子强度变化的线性项，Huckel认为这是由于电解质溶液浓度改变对溶液的介电常数影响的结果。
 * Huckel半经验方程参见WESC Activity Coefficient用户手册方程(4.2.1)
 * 方程中有两个调节参数a和b，a同Debye-Huckel方程，b无明确的物理意义，只是Huckel认为与介电常数有关。
 */
public class LMHE implements LMfunc
{ 
  static final int a0 = 0; //radii
  static final int a1 = 1; //b
  static final double A0 = 0.509;
  static final double B0 = 3.291;
  static final double temp0 = 298.15;
  static int Zc;
  static int Za;
  static int Va;
  static int Vc;
  static int V;
  static double temp = temp0;
  static double A = A0;
  static double B = B0;
  
  public LMHE(int tZc, int tZa, double ttemp){
	  Zc = tZc;
	  Za = tZa;
	  Vc = Za;
	  Va = Zc;
	  V = Va+Vc;
	  temp = ttemp;
	  A = A0*Math.pow(temp0/temp, 1.5);
	  B = B0*Math.pow(temp0/temp, 0.5);
  }
  
  public double[] initial(){
	  double[] a = new double[2];
	  a[a0] = 0.3;
	  a[a1] = 0.2;
	  return a;
  } //initial

  public double val(double[] x, double[] a){
	  double I = 0.5*(Va*x[0]*Math.pow(Za, 2)+Vc*x[0]*Math.pow(Zc, 2)); //I ionic strength
	  return (-Math.abs(Za*Zc)*A*Math.sqrt(I))/(1+B*a[a0]*Math.sqrt(I)) + a[a1]*I;
  } //val
  
  public double grad(double[] x, double[] a, int a_k){
	  if(a_k == a0){
		  double I = 0.5*(Va*x[0]*Math.pow(Za, 2)+Vc*x[0]*Math.pow(Zc, 2)); //I ionic strength
		  return (Math.abs(Za*Zc)*A*I*B)/(Math.pow(1+B*a[a0]*Math.sqrt(I),2));
	  }
	  if(a_k == a1){
		  double I = 0.5*(Va*x[0]*Math.pow(Za, 2)+Vc*x[0]*Math.pow(Zc, 2)); //I ionic strength
		  return I;
	  }
	  else {
		  assert false;
		  return 0.;
	  }
  } //grad
} //DHTest
